package com.lavender.aop;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


/**
 * 一：
 * Spring：需要配置@EnableAspectJAutoProxy：注册AspectJAnnotationAutoProxyCreator到Spring容器。
 * Spring 5.x：默认使用JDK动态代理，参考@EnableAspectJAutoProxy注解。
 *
 * Spring Boot写法： Spring Boot不需要再配置@EnableAspectJAutoProxy注解，会使用AopAutoConfiguration类来装配AOP（自动装配）。
 * 参考：{@link org.springframework.boot.autoconfigure.aop.AopAutoConfiguration}。
 * Spring Boot 1.x：默认使用JDK动态代理。默认情况下配置文件中是不会配置 spring.aop.proxy-target-class。
 * Spring Boot 2.x：默认使用Cglib动态代理。默认情况下配置文件中是不会配置 spring.aop.proxy-target-class。
 *
 * 二：
 * 问题：为什么Spring Boot 2.x中要使用Cglib来作为默认代理？
 * 参考：https://juejin.cn/post/6844903982721138696（防止人们不使用接口时出现讨厌的代理问题。）
 * 原因：yml配置spring.aop.proxy-target-class=false中可测试。测试类：{@link com.lavender.aop.spring.aop.TestCommand1}。
 * 1：当配置spring.aop.proxy-target-class=false使用JDK动态代理时，会报错。
 * The bean 'userServiceImpl' could not be injected as a 'com.lavender.aop.spring.aop.service.impl.UserServiceImpl' because it is a JDK dynamic proxy that implements:
 * 	com.lavender.aop.spring.aop.service.UserService
 * 2：当使用默认的Cglib动态代理时，注入接口，注入实现类均不会报错。
 * @Autowired
 * private UserService userService;  ---> 会找到UserService接口的实现类UserServiceImpl，然后基于实现类UserServiceImpl生成代理类UserServiceImpl$$EnhancerBySpringCGLIB$$620a36fc。
 *
 * @Autowired
 * private UserServiceImpl userService; ---> 基于实现类UserServiceImpl生成代理类UserServiceImpl$$EnhancerBySpringCGLIB$$620a36fc。
 *
 * 三：如何理解动态代理时@Autowired的注入。
 * JDK动态代理：代理类 ---implements---> 接口：@Autowired时，会注入代理类。
 * Cglib动态代理：代理类 ---extends---> 原生类 ---implements---> 接口：@Autowired时，会注入代理类。
 *
 * <p>
 * 详细介绍spring boot aop的示例，写法等。
 * </p>
 * @author: zhu.chen
 * @date: 2020/12/8
 * @version: v1.0.0
 */
//@EnableAspectJAutoProxy
@SpringBootApplication
public class LavenderAopApplication {

    public static void main(String[] args) {
        SpringApplication.run(LavenderAopApplication.class, args);
    }


}
